#!/usr/bin/env python2

import argparse
import errno
import os
import sys
import time

from txtstyle.confparser import ConfParser, ConfParserException
from txtstyle.palette import Palette
from txtstyle.transformer import Transformer
from txtstyle.transformer import RegexStyle
from txtstyle.txtsconf import *

_USER_HOME_CONF_FILE = os.path.join(os.getenv('HOME'), '.txts.conf')

class Txts(object):

    def __init__(self, styles, filepath=None, color_always=False):
        self.transformer = Transformer(styles)
        self.filepath = filepath
        self.color_always = color_always

    def transform(self):
        if self.filepath:
            self._transform_file()
        elif not sys.stdin.isatty():
            self._transform_pipe()

    def _transform_file(self):
        try:
            with open(self.filepath, 'r') as infile:
                for line in infile:
                    self._style(line)
        except KeyboardInterrupt:
            pass
        except IOError, e:
            if e.errno == errno.ENOENT:
                sys.stderr.write("File not found: %s\n" % self.filepath)
            elif e.errno == errno.EPIPE:
                # broken pipe
                pass
            else:
                sys.stderr.write("%s\n" % e)
            sys.exit(e.errno)

    def _transform_pipe(self):
        try:
            while True:
                line = sys.stdin.readline()
                if not line:
                    break
                self._style(line)
        except KeyboardInterrupt:
            pass
        finally:
            sys.stdin.close()

    def _style(self, line):
        if sys.stdout.isatty() or self.color_always:
            styled_line = self.transformer.style(line.strip('\n'))
            sys.stdout.write(styled_line + '\n')
        else:
            sys.stdout.write(line)



def parse_args():
    parser = argparse.ArgumentParser(
        prog='TxtStyle',
        description='Prettifies output of console programs.')

    parser.add_argument('filepath', nargs='?', help='Path to a file.')

    group = parser.add_mutually_exclusive_group()
    group.add_argument('-p', '--palette', help='Print a palette of available styles.', action='store_true')
    group.add_argument('-n', '--name', nargs=1, help='Name of the style to apply.')
    group.add_argument('-r', '--regex', nargs=1, help='Highlight text based on the given regular expression.')

    parser.add_argument('-c', '--conf', nargs=1, help='Path to a conf file. Default is: ~/.txt.conf')
    parser.add_argument('--color-always', help='Always use color. Similar to grep --color=always.', action='store_true')
    return parser.parse_args()

def get_styles(conf_parser, style_def_name):
    try:
        return conf_parser.get_styles(style_def_name)
    except ConfParserException, e:
        sys.stderr.write("%s\n" % e)
        sys.exit(1)

def get_conf_lines(args):
    confpath = get_conf_path(args)
    with open(confpath, 'r') as f:
        return f.readlines()

def get_conf_path(args):
    if args.conf:
        # User-specified conf file
        filepath = args.conf[0]
        if not os.path.isfile(filepath):
            sys.stderr.write("File not found: %s\n" % filepath)
            sys.exit(errno.ENOENT)
        return filepath
    else:
        # User-home conf file (~/.txt.conf)
        if not os.path.isfile(_USER_HOME_CONF_FILE):
            with open(_USER_HOME_CONF_FILE, 'w+') as f:
                f.write(DEFAULT_CONF)
        return _USER_HOME_CONF_FILE

def main():
    args = parse_args()
    styles = []

    if args.palette:
        Palette().print_palette()
    elif args.name:
        conf_lines = get_conf_lines(args)
        conf_parser = ConfParser(conf_lines)
        style_def_name = args.name[0]
        styles = get_styles(conf_parser, style_def_name)
    elif args.regex:
        regex = args.regex[0]
        transforms = ['red', 'bold']
        styles = [RegexStyle(regex, transforms)]

    txts = Txts(styles, args.filepath, args.color_always)
    txts.transform()

if __name__ == "__main__":
    main()

